<?php
/**
 * @abstract 通用公共方法类
 * @author 
 * @date 
 * @version 1.0
 * @LastModified by YingnanLiu 2010-03-18 
 */
class FSUtility {
	
	const HTTP_URL_REGIX = '/http(s)?:\/\/[0-9a-zA-Z.]*/';

    /*
     * 对变量进行 JSON 编码(支持中文)
     *
     * @param mix $value                   待编码的 value ，除了resource 类型之外，可以为任何数据类型
     * return string                        编码成功则返回一个以 JSON 形式表示的 string
     */
	public static function jsonEncodeEx($value) {
	    array_walk_recursive($value, "FSUtility::jsonConvertEncodingG2U");
	    return json_encode($value);
	}
	
    /*
     * 对 JSON 格式的字符串进行解码(支持中文)
     *
     * @param string $value                 json格式的字符串
     * @param bool $assoc(When TRUE, returned objects will be converted into associative arrays. )
     * return mix                          
     */
	public static function jsonDecodeEx($value, $assoc = true) {
	    $value = json_decode($value,$assoc);
	    array_walk_recursive($value, "FSUtility::jsonConvertEncodingU2G");
	    return $value;
	}

	//内部调用方法
	public static function jsonConvertEncodingG2U(&$value, &$key) {
	    $value = iconv("GBK", "UTF-8", $value);
	}
	//内部调用方法
	public static function jsonConvertEncodingU2G(&$value, &$key) {
	    $value = iconv("UTF-8", "GBK", $value);
	}
	
    
    /**
     * JS弹出msg窗口并跳转
     *
     * @param string $msg
     * @param string $location 跳转地址,空则不跳
     */
    public static function jsAlertJump($msg='',$location='') {
        $location = trim($location);
        if(empty($location)){
            echo '<script type="text/javascript">alert("'.$msg.'")</script>';
        }else{
            if(!empty($msg)){
                echo '<script type="text/javascript">alert("'.$msg.'");window.location.href="'.$location.'"</script>';
            }else{
                echo '<script type="text/javascript">window.location.href="'.$location.'"</script>';
            }
            exit();
        }
    }

    /**
     * 跳转到某地址
     * @param string $url
     * @param int type
     * @param mixed $params
     * 参数说明：1.url，2,跳转类型，3：参数数组
     * $type = 1, js->location;
     * $type = 2, js->replace;
     * $type = 3, php->header;
     * $type = 4, meta
     * $type = 5, history.go(-1);
     */
    public static function go2($url, $type, $params = ''){
    	$paramstr='';
        if(is_array($params)&&!empty($params)){
            $paramstr = '?'.http_build_query($params);
        }else{
            if(!empty($params)){
                $paramstr = '?'.trim($params);
        	}
        }
        $url .= $paramstr;
        if($type == 1){
            echo '<script type="text/javascript">window.location="'.$url.'";</script>';
        }elseif($type == 2){
            echo '<script type="text/javascript">window.location.replace("'.$url.'");</script>';
        }elseif($type == 3){
            header("Location: ".$url);
        }elseif($type == 4){
            $delay  = 0;
            echo '<meta http-equiv="refresh" content="'.$delay.';URL='.$url.'">';
        }elseif($type == 5){
        	echo '<script type="text/javascript">history.go(-1);</script>';
        }
        return;
    }

    /**
     * 创建目录多级
     *
     * @param string $dir 路径名称
     */
    public static function mkdirs($dir) {
        if(!is_dir($dir)) {
            self::mkdirs(dirname($dir));
            mkdir($dir,0755);
        }
    }


    /**
     * 获得用户IP地址
     *
     * @return string $user_ip
     */
    public static function getUserIP() {
        if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
            $user_ip=$_SERVER["HTTP_X_FORWARDED_FOR"];
        } else {
            $user_ip=$_SERVER["REMOTE_ADDR"];
        }
        return $user_ip;
    }
    
    /**
     * 取得url的返回内容
     *
     * @param string $url
     * @return string $content
     */
    public static function callRemoteUrl($url) {
        $url = trim($url);
        $content = @file_get_contents($url);
        return $content;
    }
    
	/**
	 * 是否是有效邮箱
	 * @param string $str
	 * @return bool
	 */
	public static function isEmail($str) {
		$flag = false;
		$str = trim($str);
	    $pattern = '/^(\d|[a-zA-Z])+(-|\.|\w)*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/';
	    if (preg_match($pattern,$str)) {
	    	$flag = true;
	    }
	    return $flag;
	}
	
    /**
     * 是否是有效密码
     * @param string $str
     * @return bool
     */
    public static function isPassword($str) {
        $flag = false;
        $str = trim($str);
        $pattern = '/^[\w-]{6,16}$/';
        if (preg_match($pattern,$str)) {
            $flag = true;
        }
        return $flag;
    }
	
	/**
	 * 是否是有效邮编
	 *
	 * @param string $str
	 * @return bool
	 */
    public static function isPostalCode($str) {
        $flag = false;
        $str = trim($str);
        $pattern = '/(^[0-9]{6}$)/';
        if (preg_match($pattern,$str)) {
            $flag = true;
        }
        return $flag;
    }
    
    /**
     * 是否是有效电话
     *
     * @param string $str
     * @return bool
     */
    public static function isPhone($str) {
        $flag = false;
        $str = trim($str);
        $pattern = '/(^[0-9]{3,4}\-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^\([0-9]{3,4}\)[0-9]{3,8}$)/';
        if (preg_match($pattern,$str)) {
            $flag = true;
        }
        return $flag;
    }
    
    /**
     * 是否是有效手机号
     *
     * @param string $str
     * @return bool
     */
    public static function isMobile($str) {
        $flag = false;
        $str = trim($str);
        $pattern = '/(^0{0,1}1[0-9]{10}$)/';
        if (preg_match($pattern,$str)) {
            $flag = true;
        }
        return $flag;
    }
    
	/*
	 * 截取字符串长度，支持多字节
	 *
	 * 参数：
	*/
    public static function substring($str,$size,$skiphtml=0) {
		$ret = '';
		if ($size<=0) {
			return;
		}
		$wrap=true;
		$html=false;
		if ($size<2) $size=2;
		$j=0;
		if ($skiphtml) {
			$str=trim(strip_tags($str));
		}
		$num=strlen($str);
		for($i=0;$i<$num;$i++) {
			if ($str[$i]=="<" && !$html) {
				$html=true;
				$ret.=$str[$i];
				continue;
			}
			if ($str[$i]==">" && $html) {
				$html=false;
				$ret.=$str[$i];
				continue;
			}
			if ($html) {
				$ret.=$str[$i];
				continue;
			}
			if ($str[$i]=="\r") {
				continue;
			}
			if (($str[$i]=="\n" || $str[$i]==" " || $str[$i]=="\t") && !$space) {
				$space=true;
				$ret.=$str[$i];
				$j++;
				continue;
			} else if ($str[$i]=="\n" || $str[$i]==" " || $str[$i]=="\t") {
				$ret.=$str[$i];
				continue;
			} else {
				$space=false;
			}
			//echo "$i  ".ord($str[$i])."  $str[$i]"."  <br>"; 
			if (ord($str[$i])>128) {
				if($i<$num-1){
				  $j++;
				  $ret.=$str[$i];
				  $i++;
				  $j++;
				  $ret.=$str[$i];
				}
			}else{
			   $j++;
			   $ret.=$str[$i];
			}
			if($j>=$size) break;
		}
		return $ret;
	}
    
    
    /*------------------------以下为原有函数------------------------*/
	
    
	static public function Option($a=array(), $v=null, $all=null)
	{
		$option = null;
		if ( $all ){
			$selected = ($v) ? null : 'selected';
			$option .= "<option value='' $selected>$all</option>";
		}

		$v = explode(',', $v);
		settype($v, 'array');
		foreach( $a AS $key=>$value )
		{
			$selected = in_array($key, $v) ? 'selected' : null;
			$option .= "<option value='$key' $selected>$value</option>";
		}
		
		return $option;
	}
    /**
     * 检查是否全部为数组，不是则转化为array
     * @param mix $arr
     * @return int $arr
     */
	static public function CheckArray(&$arr) {
        if ( !is_array($arr) ) {
			if(false===$arr)
				$arr = array();
			else
				settype($arr, 'array');
		}
		return $arr;
	}
	/**
	 * 取得多维数组内某一字段的所有数值
	 *
	 * @param array    $a 数组
	 * @param array    $column 字段名
	 * @param bool     $null是否返回空值
	 * @param int      $uniq
	 * @return array
	 */
	static public function GetColumn($a=array(), $column=array('id'), $null=false, $uniq=2)
	{
		if(empty($a)) return array();
		$ret = array();
		self::CheckArray( $column );
		if(1>=count($column))
		{
			$col = $column[0];
			foreach( $a AS $one )
			{  
				$one[ $col ] = isset($one[ $col ]) ? $one[ $col ] : null;
				if ( $null || $one[ $col ] )
					$ret[] = $one[ $col ];
			}   
			if(1==$uniq)
				$ret = array_unique($ret);
			else if(2==$uniq)
				$ret = array_values(array_unique($ret));
		}
		else
		{
			foreach( $a AS $one )
			{  
				foreach($column as $col)
				{
					$one[ $col ] = isset($one[ $col ]) ? $one[ $col ] : null;
					if ( $null || $one[ $col ] )
						$ret[$col][] = $one[ $col ];
				}
			}  

			foreach($column as $col)
			{
				if(1==$uniq)
					$ret[$col] = isset($ret[$col]) ? array_unique($ret[$col]) : array();
				else if(2==$uniq)
					$ret[$col] = isset($ret[$col]) ? array_values(array_unique($ret[$col])) : array();
			}
		}

		return $ret;
	}

	/* support 2-level now */
	static public function AssColumn($a=array(), $column='id', $scolumn=null)
	{
		if(empty($a)) return array();
		$two_level = is_null($scolumn) ? false : true ;

		$ret = array();
		if ( false == $two_level )
		{   
			foreach( $a AS $one )
			{   
				$ret[ $one[$column] ] = $one;
			}   
		}   
		else
		{   
			foreach( $a AS $one )
			{   
				$ret[ $one[$column] ][ $one[$scolumn] ] = $one;
			}
		}
		return $ret;
	}


	static public function GetHumanTime($time=null, $stress=1)
	{
		$now = time();
		$time = is_numeric($time) ? $time : strtotime($time);

		$interval = $now - $time;

        switch( $stress )
        {
            case 1:
                if ( $interval > 31536000){//365*86400
                    return floor($interval/(31536000)).'年前';
                }
                else if ( $interval > 2592000){//30*86400
                    return floor($interval/(2592000)).'月前';
                }
                else if ( $interval > 604800){////7*86400
                    return floor($interval/(604800)).'周前';
                }
                else if ( $interval > 86400 ){
                    return floor($interval/(86400)).'天前';
                }
                else if ( $interval > 3600 ){
                    return floor($interval/(3600)).'小时前';
                }
                else if ( $interval > 60 ){
                    return floor($interval/(60)).'分钟前';
                }
                else if ( $interval > 0 ) { 
                        return $interval.'秒前';
                }
                else
                    return '刚刚';
            case 2:
                return date('Y-m-d', $time);
            case 3:
                return date('Y-m-d H:i', $time);
		}
	}

	static public function Charset($character = 'utf-8')
	{
		header("Content-type:text/html;charset={$character}");
	}


	/**
	 * Return the mime-type
	 * @param string $filename file name
	 * @return string MimeType
	 */
	static public function GetMimeType($filename, $ext=null) {
		if(empty($ext))
		{
			preg_match('/\.(.*?)$/', $filename, $m);    # Get File extension for a better match
				$ext = $m[1];
		}
		switch($ext){
			case 'js': return 'application/javascript';
			case 'json': return 'application/json';
			case 'jpg': case 'jpeg': case 'jpe': return 'image/jpg';
			case 'png': case 'gif': case 'bmp': return 'image/'.strtolower($m[1]);
			case 'css': return 'text/css';
			case 'xml': return 'application/xml';
			case 'html': case 'htm': case 'php': return 'text/html';
			default: 
			if(function_exists('mime_content_type')){ # if mime_content_type exists use it.
				$m = mime_content_type($filename);
			}else if(function_exists('')){    # if Pecl installed use it
				$finfo = finfo_open(FILEINFO_MIME);
				$m = finfo_file($finfo, $filename);
				finfo_close($finfo);
			}else{    # if nothing left try shell
				if(strstr($_SERVER[HTTP_USER_AGENT], 'Windows')){ # Nothing to do on windows
					return ''; # Blank mime display most files correctly especially images.
				}
				if(strstr($_SERVER[HTTP_USER_AGENT], 'Macintosh')){ # Correct output on macs
					$m = trim(exec('file -b --mime '.escapeshellarg($filename)));
				}else{    # Regular unix systems
					$m = trim(exec('file -bi '.escapeshellarg($filename)));
				}
			}
			$m = explode(';', $m);
			return trim($m[0]);
		}
	}

    /**
     * 将大五码转化为国标码，可能带来错误的BUG
     * 暂时先这样用着；
     * @param string $in
     * @return string
     */
    static public function BigToGb( $in )
    {
        $ulen = mb_strlen($in, 'UTF-8');
        $in1 = @iconv('UTF-8//IGNORE', 'BIG5//IGNORE', $in);
        $blen = mb_strlen($in1, 'BIG5');
        if ( $blen !== $ulen )
        {
            return $in;
        }
        $in2 = @iconv('BIG5//IGNORE', 'GB2312//IGNORE', $in1);
        $out = @iconv('GB2312//IGNORE', 'UTF-8//IGNORE', $in2);
        return $out;
    }


	static public function MbStrlen(&$string, $trim=1)
	{
		if($trim)
			return mb_strlen(str_replace("\r\n", "\n", trim(html_entity_decode($string))));
		else
			return mb_strlen(str_replace("\r\n", "\n", html_entity_decode($string)));
	}
	
	/**
	 * 截取字符串
	 *
	 * @param $string
	 * @param $length
	 * @param $etc
	 * @param $break_words
	 * @param $middle
	 * @return string
	 */
	static public function Truncateutf8($string, $length = 80, $etc = '...', $break_words = false, $middle = false){
		if ($length == 0)
		return '';

		// 不要使用html_entity_decode，发现严重安全漏洞
		//$string = html_entity_decode($string,ENT_QUOTES,'UTF-8');
		$string = strip_tags($string);

		mb_internal_encoding('UTF-8');
		$string=str_replace('&nbsp;','',$string);
		if (mb_strlen($string) > $length) {
			//$length -= min($length, mb_strlen($etc));
			if (!$break_words && !$middle) {
				$string = preg_replace('/\s+?(\S+)?$/', '', mb_substr($string, 0, $length+1));
			}
			if(!$middle) {
				return mb_substr($string, 0, $length) . $etc;
			} else {
				return mb_substr($string, 0, $length/2) . $etc . mb_substr($string, -$length/2);
			}
		} else {
			return $string;
		}
	}

	
	/**
	 * 计算microtime格式的时间差
	 *
	 * @param string $time_start
	 * @param string $time_end
	 * @return string
	 */
	static public function GetTimeDiff($time_start, $time_end)
	{
		$c = explode(' ', $time_start);
		$d = explode(' ', $time_end);
		return $d[1]-$c[1]+$d[0]-$c[0];
	}
	
	/**
	 * 获取用户的浏览器信息
	 * @return 浏览器类型
	 */
	 static public function GetUserExplorer()
	 {
	 	$os=$_SERVER['HTTP_USER_AGENT'];// 浏览者操作系统及浏览器
	 	if(strpos($os,'NetCaptor'))	$explorer='NetCaptor';
		elseif(strpos($os,'Opera'))	$explorer='Opera';
		elseif(strpos($os,'Firefox'))	$explorer='Firefox';
		elseif(strpos($os,'MSIE 6'))	$explorer='MSIE 6.x';
		elseif(strpos($os,'MSIE 5'))	$explorer='MSIE 5.x';
		elseif(strpos($os,'MSIE 4'))	$explorer='MSIE 4.x';
		elseif(strpos($os,'Netscape'))	$explorer='Netscape';
		else	$explorer='Other';
		return $explorer;
	 }
	 
	/**
	 * 获取用户的操作系统
	 * @return 操作系统类型
	 */
	 static public function GetUserOs()
	 {
	 	$os=$_SERVER['HTTP_USER_AGENT'];// 浏览者操作系统及浏览器
		// 分析操作系统
		if(strpos($os,'Windows NT 5.0'))$os='Windows 2000';
		elseif(strpos($os,'Windows NT 5.1'))$os='Windows XP';
		elseif(strpos($os,'Windows NT 5.2'))$os='Windows 2003';
		elseif(strpos($os,'Windows NT'))$os='Windows NT';
		elseif(strpos($os,'Windows 9'))$os='Windows 98';
		elseif(strpos($os,'unix'))$os='Unix';
		elseif(strpos($os,'linux'))$os='Linux';
		elseif(strpos($os,'SunOS'))$os='SunOS';
		elseif(strpos($os,'BSD'))$os='FreeBSD';
		elseif(strpos($os,'Mac'))$os='Mac';
		else $os='Other';
		return $os;
	 }
	/**
	 * Return the raw POST vars
	 * @return   dict   {<post-param-1>: <val>, <post-param-2>: <val>, ...}
	 *
	 * PHP does some weird things with POST var names.  Two examples of this are:
	 * 1.  If you have vars named like this x[0], x[1], etc., then PHP will
	 * put those into an array for you.
	 * 2.  If you any dots (.) in your post var names, then PHP will replace
	 * those with underscores.
	 *
	 * This function returns the POST vars without any of those transformations
	 * applied.  It may be useful to do the same thing for GET parameters.
	 *
	 * Note that the vars returned by this function will never be slash-escaped,
	 * regardless of whether you have magic quotes on or off.  yay.
	 *
	 * IMPORTANT NOTE: this function currently fails to handle 2 things being POSTed
	 * with the same value.
	 *
	 */
	static public function PhpInputRawPostVars() {
	  global $PHP_INPUT_RAW_POST_VARS;
	  if (isset($PHP_INPUT_RAW_POST_VARS)) {
		return $PHP_INPUT_RAW_POST_VARS;
	  }

	  $post_string = file_get_contents('php://input');
	  $assignments = empty($post_string) ? array() : explode('&', $post_string);
	  $post_vars = array();
	  foreach ($assignments as $asst) {
		if (strstr($asst, '=')) {
		  list($param_e, $val_e) = explode('=', $asst, 2);
		  $param = urldecode($param_e);
		  $val = urldecode($val_e);
		} else {
		  $param = urldecode($asst);
		  $val = '';
		}
		$post_vars []= array($param, $val);
	  }

	  return ($PHP_INPUT_RAW_POST_VARS = $post_vars);

	}

	static public function GetDebugMode()
	{
		if(defined('DEBUG_MODE') && DEBUG_MODE)
			return 1;
		return 0;
	}

    static public function Convert2UTF8($from_string, $from_encoding='GBK', $to_encoding='UTF-8')
    {
        $to_string = iconv($from_encoding, $to_encoding.'//TRANSLIT', $from_string);
        if($from_string===iconv($to_encoding, $from_encoding.'//TRANSLIT', $to_string))
			return $to_string;

        $to_string = mb_convert_encoding($from_string, $to_encoding, $from_encoding);
        if($from_string===mb_convert_encoding($to_string, $from_encoding, $to_encoding))
			return $to_string;
        return $from_string;
    }


}
